home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
BBS in a Box 7
/
BBS in a Box - Macintosh - Volume VII (BBS in a Box) (January 1993).iso
/
Files
/
Tele
/
C
/
Comet2.1.3.cpt
/
Comet
/
3270com.c
< prev
next >
Wrap
Text File
|
1991-08-22
|
29KB
|
1,237 lines
/*
* COPYRIGHT 1987 CORNELL UNIVERSITY; All Rights Reserved
* Please see detailed copyrights and disclaimers in "notices.h"
*/
/***************************************************************************
* This is the 3270 datastream command processor. It is passed a pointer *
* to a string containing one 3270 command and associated orders and/or *
* data and the length of the string to process. *
* written by Peter Hoyt, Cornell Computer Services
* and bloody well extensively modified by kevin eric saunders!
***************************************************************************/
#include <em.h>
#include <3270.h>
#ifdef USEMACTCP
#include "mactcp.h"
#endif
/* the possible emulator states ... */
#define CMNORM 0
#define CMCONT 1
#define CMWRITE 2
#define CMWRITE1 3
#define CMEAT 4
#define CMEAT1 5
#define CMSBA 6
#define CMSBA1 7
#define CMRA 8
#define CMRA1 9
#define CMRA2 10
#define CMEUA 11
#define CMEUA1 12
#define CMSF 13
char commandmap[256]; /* map of write orders to avoid switch overhead */
cmd(ptr, length)
register unsigned char *ptr;
register int length;
{
register unsigned char * curptr;
register unsigned char * mapend = smap_end;
register unsigned char thechar; /* current data/command byte */
register short haddata; /* the last byte processed was data */
unsigned char * attp;
unsigned char achar;
short acount;
short cnt;
struct token * tkptr;
if (length == 0)
return(0);
if (cmdstate) {
/* we were in the middle of handling a 3270 command string;
resume where we left off. curptr & emdp->savcount states must
be maintained */
curptr = emdp->savcurptr;
haddata = emdp->savdata;
if (cmdstate == CMCONT) {
/* we just needed to restore state before proceeding */
thechar = *ptr++;
--length;
}
else if (cmdstate == CMWRITE1)
/* predominant case */
goto CMDWRITE1;
switch (cmdstate) {
case CMWRITE:
goto CMDWRITE;
case CMSF:
goto CMDSF;
case CMSBA:
goto CMDSBA;
case CMSBA1:
goto CMDSBA1;
case CMRA:
goto CMDRA;
case CMRA1:
goto CMDRA1;
case CMRA2:
goto CMDRA2;
case CMEAT:
goto CMDEAT;
case CMEAT1:
goto CMDEAT1;
case CMEUA:
goto CMDEUA;
case CMEUA1:
goto CMDEUA1;
}
}
else {
cmdstate = CMCONT;
thechar = *ptr++;
--length;
}
switch (thechar) {
case EW:
/* erase / write command */
case EWA: {
/* erase / write alternate */
/* reset the screen buffer & reposition cursor
if most recent action (or cmd) not a CLEAR */
if (!(emdp->event_reg & CLEAR_KEY)) {
modflg = SCRALLMOD;
mem_clear(scr_map, emdp->screensize, (char) IBMNULL);
cursor_ptr = scr_map;
current_attr = NULL;
newibmcursor();
}
/* these guys fall into normal write */
/* we may spend a lot of time in here now */
}
case W: {
/* write command */
/* TODO lookahead crap */
if (length == 4 && *(ptr + 1) == 0x11)
/* check for special case of using a lone SBA */
emdp->scr_flag = 1;
else {
/* to establish screen buffer ptr for a read command that
is to follow immediately */
emdp->scr_flag = 0;
emdp->scr_org = scr_map;
}
/* ignore command if no WCC ? */
/* kevin TODO should not ignore EAU! 3-2 3270 guide ? */
CMDWRITE:
if (--length < 0) {
cmdstate = CMWRITE;
goto end_write;
}
thechar = *ptr++;
/* next char has WCC command stuff in it */
if (thechar & SNDALRM)
emdp->event_reg |= SOUND_ALARM;
/* process WCC */
if (thechar & KYBDRST)
emdp->event_reg |= KYBD_RESTORE;
/* execute later */
if ((thechar & RMDT) && current_attr != NULL) {
/* reset MDT */
attp = current_attr;
*attp &= ~MDT;
while ((attp = look_attr(attp, FWD)) != current_attr)
*attp &= ~MDT;
}
curptr = cursor_ptr;
/* default */
haddata = FALSE;
/* last char. processed not data */
firstp = NULL;
length = ft_check(ptr, length);
/* TODO lookahead crap */
/* check for file transfer */
while (TRUE) {
/* process orders & data */
CMDWRITE1:
if (--length < 0) {
cmdstate = CMWRITE1;
goto end_write;
}
thechar = *ptr++;
if (!commandmap[thechar]) {
/* normal data for screen display */
if (!firstp)
firstp = curptr;
thechar = ebctoasc[thechar];
*curptr++ = thechar;
if (curptr >= mapend) {
set_mod(firstp, curptr - firstp);
curptr = scr_map;
firstp = NULL;
}
haddata = TRUE;
if (emdp->matchinput) {
/* we're trying to match input characters */
if (matchtoken(thechar))
resumetokens(emdp);
}
continue;
/* for program tab */
}
else {
switch (thechar) {
/* check for orders */
/* not all orders are supported */
case 0x2c: /* modify field */
case 0x29: /* start field extended */
case 0x28: /* set attribute */
{
if (thechar != 0x28) {
CMDEAT:
if (--length < 0) {
cmdstate = CMEAT;
goto end_write;
}
thechar = *ptr++;
}
else
thechar = 1;
for (emdp->savcount = (thechar * 2); emdp->savcount--; ) {
/* eat unwanted type/value pairs */
CMDEAT1:
if (--length < 0) {
cmdstate = CMEAT1;
goto end_write;
}
thechar = *ptr++;
}
haddata = FALSE;
break;
}
case 0x08: {
/* graphics escape is ignored */
haddata = FALSE;
break;
}
case SF: {
/* start field */
unsigned char * nfield;
if (firstp) {
/* do set mod for touched range */
set_mod(firstp, curptr - firstp);
firstp = NULL;
}
CMDSF:
if (--length < 0) {
cmdstate = CMSF;
goto end_write;
}
thechar = *ptr++;
if (thechar & HOSTPROT)
thechar |= PROT;
else
thechar &= ~PROT;
thechar &= 0x1F;
/* see if the new field needs to have modflg set on its range */
if (modflg < SCRALLMOD) {
nfield = look_attr(curptr, BACK);
if ((*nfield & emdp->realattr)
!= (thechar & emdp->realattr)) {
nfield = look_attr(curptr, FWD);
if (nfield > curptr) {
acount = nfield - curptr;
}
else {
acount = nfield - scr_map + mapend - curptr;
}
set_mod(curptr, acount);
}
}
*curptr++ = thechar; /* mask out irrelevant part */
if (curptr >= mapend)
curptr = scr_map;
haddata = FALSE;
break;
}
case SBA: {
/* set buffer address */
if (firstp) {
/* do set mod for touched range */
set_mod(firstp, curptr - firstp);
firstp = NULL;
}
CMDSBA:
if (--length < 0) {
cmdstate = CMSBA;
goto end_write;
}
thechar = *ptr++;
emdp->savcount = ((short) (thechar & 0x3f)) * 64;
CMDSBA1:
if (--length < 0) {
cmdstate = CMSBA1;
goto end_write;
}
thechar = *ptr++;
emdp->savcount += (short) (thechar & 0x3f);
curptr = scr_map + emdp->savcount;
while (curptr >= mapend)
curptr -= emdp->screensize;
if (emdp->scr_flag) {
emdp->scr_flag = 0; /* set special pointer */
emdp->scr_org = curptr; /* this one time */
}
haddata = FALSE;
break;
}
case IC: {
/* insert cursor */
cursor_ptr = curptr;
newibmcursor();
haddata = FALSE;
break;
}
case RA: {
/* repeat to address */
if (firstp) {
/* do set mod for touched range */
set_mod(firstp, curptr - firstp);
firstp = NULL;
}
/* first figure address itself */
CMDRA:
if (--length < 0) {
cmdstate = CMRA;
goto end_write;
}
thechar = *ptr++;
emdp->savcount = ((short) (thechar & 0x3f)) * 64;
CMDRA1:
/* then figure distance to it */
if (--length < 0) {
cmdstate = CMRA1;
goto end_write;
}
thechar = *ptr++;
emdp->savcount += (short) (thechar & 0x3f);
/* get character to repeat */
CMDRA2:
if (--length < 0) {
cmdstate = CMRA2;
goto end_write;
}
thechar = *ptr++;
/* are we ahead of or behind the cursor ? */
if (emdp->savcount > emdp->screensize)
/* keep it inside the buffer! */
emdp->savcount = emdp->screensize;
/* translate emdp->savcount from address to counter */
if (scr_map + emdp->savcount > curptr)
emdp->savcount -= curptr - scr_map;
else
emdp->savcount += mapend - curptr;
if (curptr + emdp->savcount > mapend) {
/* will we wrap? */
cnt = (mapend - curptr);
mem_clear(curptr, cnt, ebctoasc[thechar]);
set_mod(curptr, cnt);
mem_clear(scr_map, emdp->savcount - cnt, ebctoasc[thechar]);
set_mod(scr_map, emdp->savcount - cnt);
}
else {
mem_clear(curptr, emdp->savcount, ebctoasc[thechar]);
set_mod(curptr, emdp->savcount);
}
curptr += emdp->savcount;
/* fix the buffer pointer */
while (curptr >= mapend)
/* was if */
curptr -= emdp->screensize;
haddata = FALSE;
break;
}
case EUA: {
/* erase unprotected to address */
if (firstp) {
/* do set mod for touched range */
set_mod(firstp, curptr - firstp);
firstp = NULL;
}
/* ugh.. not thoroughly tested */
CMDEUA:
if (--length < 0) {
cmdstate = CMEUA;
goto end_write;
}
thechar = *ptr++;
emdp->savcount = ((short) (thechar & 0x3f)) * 64;
CMDEUA1:
if (--length < 0) {
cmdstate = CMEUA1;
goto end_write;
}
thechar = *ptr++;
emdp->savcount += (short) (thechar & 0x3f); /* calc. dist. to addr. */
if (emdp->savcount > emdp->screensize)
/* keep it inside the buffer! */
emdp->savcount = emdp->screensize;
if (scr_map + emdp->savcount > curptr)
emdp->savcount -= (curptr - scr_map);
else
emdp->savcount += (mapend - curptr);
/* must be formatted buffer */
if ((attp = look_attr(curptr, BACK)) != NULL) {
set_mod(curptr, emdp->savcount);
while (emdp->savcount-- > 0) {
/* not attr & unprotected */
if (*curptr >= ATTR && !(*attp & PROT))
*curptr = IBMNULL;
if (++curptr == mapend)
curptr = scr_map;
if (*curptr < ATTR)
attp = curptr; /* new field */
}
}
haddata = FALSE;
break;
}
case PT: {
/* program tab */
if (firstp) {
/* do set mod for touched range */
set_mod(firstp, curptr - firstp);
firstp = NULL;
}
if (haddata == FALSE) {
curptr = first_unp(curptr);
/* haddata remains false */
}
else {
while (curptr != mapend && *curptr >= ATTR) {
*curptr = IBMNULL;
set_mod(curptr++, 1);
/* EFFICIENCY */
}
if (curptr >= mapend) {
/* frought with special cases */
curptr = scr_map;
/* haddata remains true */
}
else {
/* NORMAL CASE? haddata && middle of screen */
/* HOYT: probably dosen't work & never meant to */
curptr = first_unp(curptr);
haddata = FALSE;
}
}
break;
}
}
}
/* end of switch on next order or data */
/* we have processed another order or data byte */
}
/* end while loop (write command) */
end_write:
/* branch here if orphan order */
if (firstp != NULL) {
/* do set mod for touched range */
set_mod(firstp, curptr - firstp);
firstp = NULL;
}
emdp->savcurptr = curptr;
emdp->savdata = haddata;
if (emdp->event_reg & TFTP_ON) {
/* we've gone into file transfer mode, end of cmd */
cmdcomplete();
}
return(0);
}
/* other 3270 commands follow */
case 0x02: {
/* read buffer */
read_buf();
break;
}
case 0x06: {
/* read modified unsolicited by action key */
/* most read modifies are handled by the telnet
server on the host since we pass the results
of one every time we send an action key */
read_mod();
emdp->scr_org = scr_map;
break;
}
case 0x0f: {
/* erase all unprotected */
if (current_attr) {
/* do only if formatted buffer */
eau();
/* manual is unclear on this */
emdp->event_reg |= KYBD_RESTORE;
emdp->event_reg |= SCREEN_REFRESH;
}
emdp->scr_org = scr_map;
break;
}
default: {
/* something unknown */
if (!emdp->emdisable)
beep();
break;
}
}
return();
}
/* a 3270 command is complete, indicated by receipt of IAC EOR */
cmdcomplete()
{
cmdstate = CMNORM;
if (emdp->event_reg & SOUND_ALARM) {
/* deal with postponed actions */
if (emdp->ayt_sent == 0 && !emdp->emdisable)
/* don't beep if this is just a response to an Are You There */
beep();
emdp->ayt_sent = 0;
emdp->event_reg &= ~SOUND_ALARM;
}
if (emdp->event_reg & KYBD_RESTORE) {
emdp->event_reg &= ~KYBD_RESTORE;
if (emdp->event_reg & KYBD_LOCK) {
clrkbdlock();
emdp->event_reg &= ~KYBD_LOCK;
}
if (emdp->event_reg & SYS_LOCK) {
clrsyslock();
emdp->event_reg &= ~SYS_LOCK;
}
emdp->aid_key = AID_RESET;
}
emdp->event_reg |= SCREEN_EVENT;
emdp->event_reg &= ~CLEAR_KEY;
/* most recent action no longer CLEAR */
if (*cursor_ptr < ATTR) /* reposition current attr pointer */
current_attr = cursor_ptr;
else
current_attr = look_attr(cursor_ptr, BACK);
}
/* send the current buffer to the host
Note if using only MacTCP, TC_PUT macro can be used */
read_buf()
{
register unsigned char * curptr;
register unsigned char * mapend = smap_end;
register unsigned char achar;
register short acount;
(*emdp->putchar)(emdp->aid_key);
/* return AID & cursor address */
acount = addr_12 (cursor_ptr - scr_map);
(*emdp->putchar)(acount >> 8);
(*emdp->putchar)(acount & 0xff);
for (curptr = emdp->scr_org; curptr < mapend; ) {
if ((achar = *curptr++) >= ATTR) {
/* send data */
(*emdp->putchar)(asctoebc[achar]);
}
else {
/* if new field (because of attr) */
(*emdp->putchar)(0x1d);
/* send SF order + attr */
if (achar & PROT) {
/* put the protected bit in the right place */
achar &= ~PROT;
achar |= HOSTPROT;
}
achar = achar & 0x3f;
achar |= 0x40;
if ((achar & 0x0f) <= 9) {
if ((achar & 0x30) == 0x30
|| (achar & 0x0f) > 2
|| achar == 0x41
|| achar == 0x51
)
achar |= 0x80;
}
(*emdp->putchar)(achar);
}
}
/* don't forget telnet command */
(*emdp->putchar)(0xff);
(*emdp->putchar)(0xef);
(*emdp->putflush)();
emdp->scr_org = scr_map;
}
/* Read modify logic used by both command processor & keyboard routine.
** In a real 3270 the host always issues a read modify and the terminal
** sends the most recent AID, cursor addr, & any fields with MDT set. In
** our telnet application, we perform the read modified and send the data
** when the user presses ENTER or a PF key, and the telnet server uses the
** data when the host application issues the read modified. In addition the
** local PC application must provide for the host issuing a read modified
** at any time. Ergo rather than duplicate code we made this subroutine.
*/
read_mod()
{
register unsigned char * ptr;
register unsigned char * mapend = smap_end;
register unsigned char * nullp;
unsigned char * endp;
unsigned char * nextattp;
register unsigned short thechar;
register short fieldcount;
short count;
unsigned char aid = emdp->aid_key;
(*emdp->putchar)(aid);
/* send AID & cursor addr */
if (! ((aid == RPA1)
|| (aid == RPA2)
|| (aid == RPA3)
|| (aid == RCLEAR) )) {
/* PA keys and CLEAR produce only AID, no data */
count = addr_12(cursor_ptr - scr_map);
(*emdp->putchar)(count >> 8);
(*emdp->putchar)(count & 0xff);
if (emdp->scr_org == scr_map)
/* so as not to miss a field that */
/* starts at upper left */
ptr = look_attr(scr_map + emdp->screensize - 1, FWD);
else
/* special case SBA + nothing */
ptr = look_attr(emdp->scr_org, FWD);
if (ptr == NULL) {
/* unformatted buffer */
for (ptr = emdp->scr_org; ptr < mapend; ) {
if ((thechar = *ptr++) != IBMNULL) {
/* translate character */
(*emdp->putchar)(asctoebc[thechar]);
}
}
}
else {
endp = ptr;
do {
if (*ptr & MDT) {
/* if MDT for this field, field modified */
nullp = nextattp = look_attr(ptr, FWD);
if (ptr < nextattp)
/* "normal" case */
fieldcount = (nullp - ptr);
else
/* we've wrapped */
fieldcount = (nullp - scr_map) + (smap_end - ptr);
/* note that fieldcount is 1 high for predecrement */
if (++ptr == mapend)
ptr = scr_map;
(*emdp->putchar)(0x11);
/* SBA order */
count = addr_12(ptr - scr_map);
(*emdp->putchar)(count >> 8);
(*emdp->putchar)(count & 0xff);
if (fieldcount) {
/* adjust end so consecutive nulls won't be sent */
if (nullp <= scr_map)
nullp += emdp->screensize;
while (--fieldcount && *--nullp == IBMNULL ) {
if (nullp <= scr_map)
nullp += emdp->screensize;
}
if (fieldcount)
/* we had some non-nulls & maybe some imbedded nulls */
nullp++;
if (nullp == smap_end)
nullp = scr_map;
while (ptr != nullp) {
/* now send the field */
thechar = *ptr++;
if (thechar == IBMNULL) {
if (emdp->nullsareblanks) {
/* put out a blank */
(*emdp->putchar)(0x40);
}
}
else {
/* translate character */
(*emdp->putchar)(asctoebc[thechar]);
}
if (ptr == mapend)
ptr = scr_map;
}
}
ptr = nextattp;
/* next attr */
}
/* end if MDT set .. */
else
ptr = look_attr(ptr, FWD);
/* put us on attr */
}
while (ptr != endp);
}
}
(*emdp->putchar)(0xff);
(*emdp->putchar)(0xef);
(*emdp->putflush)();
/* telnet EOR */
return();
}
/* this routine is called by cmd to process the 3270 command
erase all unprotected and by prompt to process the erase input key */
eau()
{
register unsigned char * curp;
register unsigned char * eattp;
register unsigned char * mapend = smap_end;
unsigned char * endp; /* original curp position for end test */
unsigned char * holdp; /* original curp position for set_mod */
curp = scr_map + emdp->screensize - 1;
/* start at end to wrap to top */
endp = curp = next_unp(FWD);
/* first position */
if ((eattp = curp - 1) < scr_map)
eattp += emdp->screensize;
/* attr. itself */
if (*eattp < ATTR && !(*eattp & PROT)) {
/* if it really is an attr */
current_attr = eattp;
*eattp &= ~MDT;
/* turn off MDT */
holdp = curp;
while (*curp >= ATTR) {
/* null out the field */
*curp++ = IBMNULL;
if (curp == mapend) {
set_mod(holdp, curp - holdp);
holdp = curp = scr_map;
}
}
set_mod(holdp, curp - holdp);
/* repeat until we have reached our original field */
while ((curp = next_unp(FWD)) != endp) {
if ((eattp = curp - 1) < scr_map)
eattp += emdp->screensize;
*eattp &= ~MDT;
for (holdp = curp; *curp >= ATTR; ) {
/* null out the field */
*curp++ = IBMNULL;
if (curp == mapend) {
set_mod(holdp, curp - holdp);
holdp = curp = scr_map;
}
}
set_mod(holdp, curp - holdp);
}
}
else {
/* no unprotected fields on screen */
cursor_ptr = scr_map;
newibmcursor();
/* follow the book */
current_attr = look_attr(scr_map, BACK);
}
}
ibm_make()
{
short newsize = FALSE;
if (emdp->scr_map != NULL)
/* already has IBM structures allocated ... */
return(0);
switch (emdp->ibm_type) {
case IBMMOD2: {
emdp->linecount = COL_SIZE; /* 24 */
emdp->linelength = ROW_SIZE; /* 80 */
emdp->screensize = SCREEN_SIZE;
break;
}
case IBMMOD3: {
emdp->linecount = 32;
emdp->linelength = 80;
emdp->screensize = emdp->linecount * emdp->linelength;
newsize = TRUE;
break;
}
#ifdef SUPPORTMOD4
/* emulator logic only handles <= 32 rows ... */
case IBMMOD4: {
emdp->linecount = 43;
emdp->linelength = 80;
emdp->screensize = emdp->linecount * emdp->linelength;
newsize = TRUE;
break;
}
#endif
case IBMMOD5: {
emdp->linecount = 27;
emdp->linelength = 132;
emdp->screensize = emdp->linecount * emdp->linelength;
newsize = TRUE;
break;
}
default: {
emdp->linecount = COL_SIZE;
emdp->linelength = ROW_SIZE;
emdp->screensize = SCREEN_SIZE;
break;
}
}
emdp->lastcol = emdp->linelength - 1;
emdp->lastrow = emdp->linecount - 1;
if (!memtest((long) emdp->screensize, "to make 3270 emulator")) {
return(-1);
}
emdp->scr_map = malloc(emdp->screensize); /* allocate the screen map */
if (emdp->scr_map == NULL) {
/* unlikely but conceivable */
return(-1);
}
mem_clear(emdp->scr_map, emdp->screensize, (char) IBMNULL);
if (emdp->color)
emdp->realattr = DSPMOD;
else
emdp->realattr = DSPD;
emdp->cmdstate = CMNORM;
emdp->aid_key = AID_RESET;
emdp->cursor_ptr = emdp->scr_map; /* current cursor position in screen map */
emdp->smap_end = emdp->scr_map + emdp->screensize; /* end of map */
emdp->ftsaveptr = &emdp->ftsavebuf[0]; /* TODO dynamic? ptr into buffer */
setcontext(emdp); /* update globals */
if (newsize)
setscreensize(emdp->fontsize);
newibmcursor();
return(0);
}
/* free memory used by the ibm emulator */
ibm_free(twp)
struct winds * twp;
{
if (twp->scr_map != NULL)
free(twp->scr_map);
twp->scr_map = NULL;
ftrecovermem(twp); /* free the file transfer memory */
}
ibm_init()
{
/* initialize the command map */
commandmap[PT] = TRUE;
commandmap[GE] = TRUE;
commandmap[SBA] = TRUE;
commandmap[EUA] = TRUE;
commandmap[IC] = TRUE;
commandmap[SF] = TRUE;
commandmap[RA] = TRUE;
commandmap[SA] = TRUE;
commandmap[SFE] = TRUE;
commandmap[MF] = TRUE;
}
ibm3270reset()
{
emdp->cmdstate = CMNORM;
emdp->aid_key = AID_RESET;
emdp->current_attr = NULL;
emdp->cursor_ptr = emdp->scr_map;
emdp->scr_org = scr_map;
emdp->xpos = 0;
emdp->ypos = 0;
if (emdp->scr_map != NULL) {
mem_clear(emdp->scr_map, emdp->screensize, (char) IBMNULL);
}
/* force an update */
setcontext(emdp);
newibmcursor();
/* manually update the winds struct */
if (emdp->emwindow)
(*emdp->clear_scr)();
}
/*
return the current attribute
*/
pc_attr()
{
unsigned char temp;
if (current_attr != NULL)
temp = *current_attr;
else
temp = 0;
return(temp);
}
/*
look forward or back thru screen map for attribute byte;
skips *ptr
*/
unsigned char *look_attr (ptr, direction)
register unsigned char *ptr;
char direction;
{
register unsigned char * breakp;
register unsigned char isattr = ATTR;
unsigned char * tempp;
tempp = ptr;
if (direction == FWD) {
ptr++;
/* break on end of screen */
breakp = smap_end;
while (ptr < breakp) {
if ( (*ptr++ < isattr) )
return(ptr - 1);
}
/* now break on original ptr pos */
breakp = tempp;
ptr = scr_map;
while (ptr <= breakp) {
if ( (*ptr++ < isattr) )
return(ptr - 1);
}
}
else {
/* as above */
breakp = scr_map;
while (--ptr >= breakp) {
if ( (*ptr < isattr) )
return(ptr);
}
breakp = tempp;
ptr = smap_end;
while (--ptr >= breakp) {
if ( (*ptr < isattr) )
return(ptr);
}
}
return(NULL);
/* no luck */
}
/*
returns the attribute in force for this point
*/
ibm_attr(ptr)
register unsigned char *ptr;
{
register unsigned char * breakp;
register unsigned char isattr = ATTR;
unsigned char * tempp;
ptr++; /* correct to adapt look_attr code: check *ptr TOO! */
tempp = ptr;
/* as above */
breakp = scr_map;
while (--ptr >= breakp) {
if ( (*ptr < isattr) )
return(*ptr);
}
breakp = tempp;
ptr = smap_end;
while (--ptr >= breakp) {
if ( (*ptr < isattr) )
return(*ptr);
}
return(0);
/* no attribute in force... */
}
/*
***** find the byte following the next unprotected field
*/
unsigned char *next_unp (direction)
char direction;
{
register unsigned char *ptr;
register unsigned char *nextp;
register unsigned char *endp;
ptr = cursor_ptr;
if (direction == FWD) {
if ((nextp = ptr + 1) == smap_end)
nextp = scr_map;
if (*ptr < ATTR && !(*ptr & PROT) && *nextp >= ATTR)
return(nextp);
}
else
if (--ptr < scr_map)
ptr += emdp->screensize;
if ((endp = ptr = look_attr(ptr, direction)) != NULL) {
while (TRUE) {
if ((*ptr & PROT) == FALSE) {
if ((nextp = ptr + 1) == smap_end)
nextp = scr_map;
if (*nextp >= ATTR)
/* it's data, and not just another attribute */
return(nextp);
}
if ((ptr = look_attr(ptr, direction)) == endp)
break;
}
}
return(cursor_ptr);
}
/*
***** return pointer to byte following the next unprotected field,
***** if wrap occurs return scr_map
*/
unsigned char *first_unp(start)
char * start;
{
register unsigned char *ptr;
register unsigned char *nextp;
register unsigned char *startp;
ptr = startp = start;
if ((*ptr < ATTR) && !(*ptr & PROT)) {
/* kevin -- test to verify first character not a field dropped */
if ((nextp = ptr + 1) == smap_end)
nextp = scr_map;
return(nextp);
}
while ((ptr = look_attr(ptr, FWD)) != NULL) {
if (ptr < startp)
return(scr_map);
/* if we've wrapped around, we set the pointer to buffer addr 0 */
if ((*ptr & PROT) == FALSE) {
if ((nextp = ptr + 1) == smap_end)
nextp = scr_map;
return(nextp);
/* it's data, and not just another attribute
Apparently we should not be testing this -- PT problem w/ XA
if (*nextp >= ATTR)
return(nextp);
*/
}
}
return(scr_map);
}
/*
**** generate 12 bit buffer address with appropriate IBM coding
*/
int addr_12(convarg)
int convarg;
{
register unsigned char achar;
unsigned int x;
achar = convarg / 64;
achar |= 0x40;
if ((achar & 0x0f) <= 9) {
if ((achar & 0x30) == 0x30
|| (achar & 0x0f) >= 2
|| achar == 0x41
|| achar == 0x51
)
achar |= 0x80;
}
x = achar << 8;
achar = convarg % 64;
achar |= 0x40;
if ((achar & 0x0f) <= 9) {
if ((achar & 0x30) == 0x30
|| (achar & 0x0f) >= 2
|| achar == 0x41
|| achar == 0x51
)
achar |= 0x80;
}
x |= achar;
return(x);
}
/*
***** clear an area of memory
*/
mem_clear(clearptr, len, value)
register char * clearptr;
register int len;
register char value;
{
register char * endptr;
for (endptr = clearptr + len; clearptr < endptr; )
*clearptr++ = value;
}
/* test a 3270 character stream to ascertain whether a DOWNLOAD is
being requested
check fmt:
0 1 2 3 4 5 6 7
| SBA | ? | ? | SBA | ? | ? | 1B | 1B
Presumably duplicate SBA's are a rare occurrence.
*/
ft_check(ptr, length)
register char *ptr;
register int length;
{
/*
if (length != 79)
return(length);
*/
if (*ptr != 0x11 && *(ptr + 3) != 0x11)
return (length);
if (*(ptr + 6) != 0x1b && *(ptr + 7) != 0x1b)
return(length);
emdp->event_reg |= TFTP_ON;
msetsendm(FALSE); /* turn off send menu items */
emdp->event_reg |= LINE_25;
ft_header();
(*emdp->putchar)(0xfd);
(*emdp->putchar)(ftinit ( (int) *(ptr+8), 0)); /* version number */
(*emdp->putchar)(0x00); /* zero indicates running tn */
ft_trailer();
return (0);
}
/* set modflg to reflect changed lines */
set_mod(pmod, ccount)
unsigned char * pmod; /* -> first position changed in map */
register int ccount; /* # of characters changed */
{
register int line;
register int count;
if (modflg >= SCRALLMOD)
/* the whole thing's been set already */
return;
line = (pmod - scr_map) / emdp->linelength; /* y pos */
count = pmod - (scr_map + line * emdp->linelength); /* x pos */
ccount += count;
/* add xpos to ccount so end will come out right */
for (count = 0; count < ccount; count += emdp->linelength) {
modflg |= modmask[line];
if (++line >= emdp->linecount)
/* wrap around if necessary */
line = 0;
}
}